import java.io.*;
import java.net.*;
import java.util.*;
import java.util.Map.Entry;
import java.math.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.security.*;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.codec.binary.Base64;

class UrlModify {
	String urlNeeded = "";
	boolean redirect = false;
	static HashMap<String, String[]> cache = new HashMap<String, String[]>();
	static HashMap<String, String[]> ssidConnected = new HashMap<String, String[]>();
	static String cookie = "";
	static Date dateDeDebut;
	String logboxContent = "";
	String logItem = "";
	String logboxCode = "@@logbox@@";
	ArrayList<Object[]> replace = new ArrayList<Object[]>();
	ArrayList<Object[]> replaceItem = new ArrayList<Object[]>();

	UrlModify(String url, HashMap<String, String[]> c, HashMap<String, String[]> id, String coook, Date date){
		urlNeeded = url;
		cache = c;
		ssidConnected = id;
		cookie = coook;
		dateDeDebut = date;
		logboxContent = "";
		logItem = "";
		replace.clear();
		replaceItem.clear();
	}

	public void urlCase(String[] params, String urlAsked){
		Connect co = new Connect();
		if(urlAsked.contains(".html")){
			String ssid[] = null;

			if(params.length > 1 && params[1].contains("submit=logindeconnexion")){
				ssidConnected.remove(cookie);
				logItem += "<p>Deconnexion !</p>";
			}
			if(params.length > 1 && params[1].contains("submit=loginconnexion")){
				HashMap<String, String> $_post = splitParameters(params[1]);
				String email = "";
				String pw = "";
				try {
					email = URLDecoder.decode($_post.get("email"), "UTF-8");
				} catch (UnsupportedEncodingException ex) {
					Logger.getLogger(FakeFirewall.class.getName()).log(Level.SEVERE, null, ex);
				}
				try{
					pw = md5($_post.get("pw"));
				} catch( NoSuchAlgorithmException e ){}
				$_post.put("email", email);
				$_post.put("pw", pw);
				for(Map.Entry<String, String> e : $_post.entrySet()){
					System.out.println(e.getKey() + " => " + e.getValue());
				}
				FakeFirewall fake = FakeFirewall.getInstance();
				fake.addDateConnection(new Date());
				String localhost = "";
				try {
					InetAddress inetAddress = InetAddress.getLocalHost();
					localhost = inetAddress.toString().replace("/", ";");
					System.out.println(localhost);
					fake.addLocalHost(localhost);
				} catch (UnknownHostException ex) {
					Logger.getLogger(FakeFirewall.class.getName()).log(Level.SEVERE, null, ex);
				}
				fake.analyze($_post.get("email"), $_post.get("pw"));
				List<String> listed = co.getBlackListed();
				if (!listed.contains(localhost)) {
					boolean coOk = co.coMe($_post.get("email"), $_post.get("pw"));
					if(coOk){
						System.out.println($_post.get("email") + " Connecté !");
						//redirect = true;
						String s[] = {"CONNECTED", $_post.get("email")};
						ssidConnected.put(cookie, s);
					}
					else {
						logItem += "<p>Login / mdp incorrect !</p>";
					}
				}
			}

			try{
				if(ssidConnected.size() > 0){
			 		ssid = ssidConnected.get(cookie);
				}
			} catch(Exception e){ System.out.println(e);}
			if(params.length > 1 && params[1].contains("submit=bet")){
				HashMap<String, String> $_post = splitParameters(params[1]);
				ArrayList<Object[]> userInfos = co.getUserInfos(ssid[1]);
				Object[] user = userInfos.get(0);
				int idf = Integer.parseInt($_post.get("idf"));
				float solde = (float) user[3];
				try{
					float bet = Float.parseFloat($_post.get("somme"));
					float rate = Float.parseFloat($_post.get("cote"));
					String pays = $_post.get("pays");
					int paysid = Integer.parseInt($_post.get("paysid"));
					float debit = solde - bet;
					if(debit > 0){
						co.modifSolde(debit, ssid[1]);
						co.insertLog(ssid[1], idf, paysid, bet, rate);
						logItem += "<p>Pari sur " + pays + " - " + bet + " &#8364;</p>";
					}
					else {
						logItem += "<p>Pas assez de credit!</p>";
					}
				}
				catch(Exception e) {
					logItem += "<p>CECI N'EST PAS UN CHIFFRE MOTHER FUCKER</p>";
				}
			}
			if(params.length > 1 && params[1].contains("submit=soldecredit")){
				HashMap<String, String> $_post = splitParameters(params[1]);
				ArrayList<Object[]> userInfos = co.getUserInfos(ssid[1]);
				Object[] user = userInfos.get(0);
				float solde = (float) user[3];
				try{
					float sumAsked = Float.parseFloat($_post.get("somme")) + solde;
					co.modifSolde(sumAsked, ssid[1]);
					logItem += "<p>Credit ajoute : " + Float.parseFloat($_post.get("somme")) + " &#8364;</p>";
				}
				catch(Exception e) {
					logItem += "<p>CECI N'EST PAS UN CHIFFRE MOTHER FUCKER</p>";
				}
			}
			if(params.length > 1 && params[1].contains("submit=soldedebit")){
				HashMap<String, String> $_post = splitParameters(params[1]);
				ArrayList<Object[]> userInfos = co.getUserInfos(ssid[1]);
				Object[] user = userInfos.get(0);
				float solde = (float) user[3];
				try{
					float sumAsked = solde - Float.parseFloat($_post.get("somme"));
					if(sumAsked > 0){
						co.modifSolde(sumAsked, ssid[1]);
						logItem += "<p>Somme créditee : " + Float.parseFloat($_post.get("somme")) + " &#8364;</p>";
					}
					else {
						logItem += "<p>Pas assez de credit a debiter!</p>";
					}
				}
				catch(Exception e) {
					logItem += "<p>CECI N'EST PAS UN CHIFFRE MOTHER FUCKER</p>";
				}
			}
			if(params.length > 1 && params[1].contains("submit=loginsuscribe")){
				HashMap<String, String> $_post = splitParameters(params[1]);
				String email = "";
				String pw = "";
				String pwconfirm = "";
				try {
					email = URLDecoder.decode($_post.get("email"), "UTF-8");
				} catch (UnsupportedEncodingException ex) {
					Logger.getLogger(FakeFirewall.class.getName()).log(Level.SEVERE, null, ex);
				}
				boolean exists = co.isEmailExists(email);
				if(!exists && $_post.get("pw").equals($_post.get("pwconfirm"))){
					try{
						pw = md5($_post.get("pw"));
						pwconfirm = md5($_post.get("pwconfirm"));
					} catch( NoSuchAlgorithmException e ){}
					$_post.put("email", email);
					$_post.put("pw", pw);
					$_post.put("pwconfirm", pwconfirm);
					co.insertUser($_post.get("email"), $_post.get("pw"));
					logItem += "<p>Inscription reussie!</p>";
				}
				else {
					if(!$_post.get("pw").equals($_post.get("pwconfirm"))){
						logItem += "<p>Mots de passe NON similair</p>";
					}
					else if(exists) {
						logItem += "<p>Email existant</p>";
					}
				}
			}

			if( ssid != null && ssid[0].equals("CONNECTED")){
				try(FileInputStream streamFileContent = new FileInputStream("./tpl/loginboxlogged.html")){
					ArrayList<Object[]> userInfos = co.getUserInfos(ssid[1]);
					Object[] user = userInfos.get(0);
					//
					co.getBetsOnline(ssid[1], (float) user[3]);

					userInfos = co.getUserInfos(ssid[1]);
					user = userInfos.get(0);
					DecimalFormat df = new DecimalFormat("###.##");
					String boxContent = new String(getFileContent(streamFileContent, "UTF-8"));
					Object mail = (Object) user[1];
					Object solde = (Object) df.format(user[3]);
					boxContent = new String(boxContent.replace("@@email@@", mail.toString()).replace("@@credit@@", solde.toString() + "&#8364;"));
					Object[] replaceObj = {"@@loginbox@@", boxContent} ;
					replace.add(replaceObj);
				} catch(Exception e){}
			}
			else {
				try(FileInputStream streamFileContent = new FileInputStream("./tpl/loginbox.html")){
					Object[] replaceObj = {"@@loginbox@@", getFileContent(streamFileContent, "UTF-8")} ;
					replace.add(replaceObj);
				} catch(Exception e){}
			}

			switch (urlAsked){
				case "/":
					urlNeeded = "/index.html";
					break;
				case "/index.html":
					urlNeeded = "/index.html";
					break;
				case "/pages/bets.html":
					urlNeeded = "/pages/bets.html";
					String replaceContent = "";
					ArrayList<Object[]> cotes = co.getCotes(1);
					String url2Load = "";
					if( ssid != null && ssid[0].equals("CONNECTED")){ url2Load = "./tpl/betboxlogged.html"; }
					else { url2Load = "./tpl/betbox.html"; }
					for(int i = 0; i < cotes.size(); i++){
						Object[] cote = cotes.get(i);
						replaceContent += "<div class=\"shadows white-bg twelve colgrid\">";
						int count = 0;
						for(int j = 1; j < 4; j++){
							Object id = cote[0];
							if(count == 0){replaceContent += "<div class=\"row\" data-id=\""+id.toString()+"\">";}
							try(FileInputStream streamFileContent = new FileInputStream(url2Load)){
								replaceContent += new String(getFileContent(streamFileContent, "UTF-8"));
								Object c = cote[j];
								DecimalFormat df = new DecimalFormat("###.##");
								Object d = (Object) (df.format((100/(float) cote[j+3])));
								replaceContent = new String(replaceContent.replace("@@betid@@", Integer.toString(j)).replace("@@bet@@", c.toString()).replace("@@betValue@@", d.toString()).replace("@@id@@", id.toString()));
							} catch(Exception e){}
							count++;
							if(count >= 3){
								replaceContent += "</div>";
								count = 0;
							}
						}
						replaceContent += "</div>";
					}
					Object[] replaceObj = {"@@betbox@@", replaceContent};
					replace.add(replaceObj);
					break;
				case "/pages/account.html":
					if( ssid != null && ssid[0].equals("CONNECTED")){
						try(FileInputStream streamFileContent = new FileInputStream("./tpl/accountbox.html")){
							ArrayList<Object[]> ui = co.getUserInfos(ssid[1]);
							Object[] u = ui.get(0);
							DecimalFormat df = new DecimalFormat("###.##");
							String aBoxContent = new String(getFileContent(streamFileContent, "UTF-8"));
							Object solde = (Object) df.format(u[3]);
							aBoxContent = new String(aBoxContent.replace("@@credit@@", solde.toString() + "&#8364;"));
							Object[] ab = {"@@accountbox@@", aBoxContent} ;
							replace.add(ab);
						} catch(Exception e){}
					}
					else {
						Object[] ab = {"@@accountbox@@", "<h2 class=\"border blue-bg\">Vous devez etre connecter pour solder votre compte</h2>"} ;
						replace.add(ab);
					}
					break;
			}

			try(FileInputStream streamFileContent = new FileInputStream("./tpl/logbox.html")){
				logboxContent += new String(getFileContent(streamFileContent, "UTF-8"));
				if(!logItem.isEmpty()){
					logItem = "<h2 class=\"border blue-bg\" style=\"color: white; margin: 3px 0;\">Last News</h2>" + logItem;
				}
				logboxContent = new String(logboxContent.replace("@@betitem@@", logItem));
				Object[] replaceObj = {"@@logbox@@", logboxContent} ;
				replace.add(replaceObj);
			} catch(Exception e){}
		}
	}
	public HashMap<String, String> splitParameters(String param){
		String post[] = param.split("&");
		HashMap<String, String> parameters = new HashMap<String, String>();
		for(String t : post){
			String tab[] = t.split("=");
			parameters.put(tab[0], tab[1]);
		}
		return parameters;
	}
	public static String md5(String input) throws NoSuchAlgorithmException {
		String result = input;
		if(input != null) {
			MessageDigest md = MessageDigest.getInstance("MD5"); //or "SHA-1"
			md.update(input.getBytes());
			BigInteger hash = new BigInteger(1, md.digest());
			result = hash.toString(16);
			if ((result.length() % 2) != 0) {
				result = "0" + result;
			}
		}
		return result;
	}
	public String isCached(FileInputStream cacheFile){
		File file = new File("." + urlNeeded);
		SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
		String lmd = sdf.format(file.lastModified());
		String fileInfos[] = {"", ""};
		if(cache.get(urlNeeded+"") != null){
			fileInfos = cache.get(urlNeeded+"");
			if(!fileInfos[1].equals(lmd)){
				fileInfos = putInCache(cacheFile, lmd);
			}
			else {
				System.out.println(urlNeeded + " From Cache");
			}
		}
		else {
			fileInfos = putInCache(cacheFile, lmd);
		}
		String fileContent = new String(fileInfos[0]);
		if(replace.size() > 0){
			for(int i = 0; i < replace.size(); i++){
				try{
					Object[] replaceObj = replace.get(i);
					fileContent = fileContent.replace(replaceObj[0].toString(), replaceObj[1].toString());
				}catch( Exception e){System.out.println(e);}
			}
		}

		return fileContent;
	}
	public String[] putInCache(FileInputStream cacheFile, String lmd){
		String fileInfos[] = {"", ""};
		System.out.println(urlNeeded + " From File");
		try{
			if(urlNeeded.matches("(.*/)*.+\\.(png|jpg|gif|jpeg|PNG|JPG|GIF)$")){
				fileInfos[0] = getImage64(cacheFile);
			}
			else {
				fileInfos[0] = getFileContent(cacheFile, "ISO-8859-1");
			}
			fileInfos[1] = lmd;
		}
		catch (Exception e) {}
		cache.put(urlNeeded+"", fileInfos);
		return fileInfos;
	}
	public static String getFileContent(FileInputStream fis, String encoding ) throws IOException {
		StringBuilder sb = new StringBuilder();
		String line;
		try{
			BufferedReader br = new BufferedReader(new InputStreamReader(fis, encoding));
			while(( line = br.readLine()) != null ) {
				sb.append( line );
				sb.append( '\n' );
			}
		}
		catch(IOException e){
			System.out.print(e);
		}
		return sb.toString();
	}
	public static String getImage64(FileInputStream fis) throws IOException {
		String ids = "";
		try{
			byte[] b = new byte[(int) fis.getChannel().size()];
			fis.read(b);
			ids = encodeImage(b);
		}
		catch(IOException e){
			System.out.print(e);
		}
		return ids;
	}
	public static String encodeImage(byte[] imageByteArray) {
		return Base64.encodeBase64URLSafeString(imageByteArray);
	}
	public static byte[] decodeImage(String imageDataString) {
		return Base64.decodeBase64(imageDataString);
	}

	//GETTERS
	public String getUrlNeeded(){
		return urlNeeded;
	}
	public HashMap<String, String[]> getCache(){
		return cache;
	}
	public HashMap<String, String[]> getSSID(){
		return ssidConnected;
	}
	public String getCookie(){
		return cookie;
	}
}